/**
 * symbol是ES6中引入的原始数据类型，他的作用用来表示唯一的值
 */

const s1 = Symbol()
const s2 = Symbol()
console.log(s1 === s2) //false
//两者都是Symbol类型，但是是两个不同的值
console.log(s1.toString()) //Symbol()
console.log(s2.toString()) //Symbol()

const s3=Symbol('foo') //可以给Symbol添加一个描述,用于描述这个Symbol的用途与调试,不会影响到Symbol的唯一性
//需要注意:描述既不是键,也不是值,只是用来给人看的

//symbol作用1 
// 作为对象的属性名,可以避免对象的属性名冲突
const name = Symbol('name')

const obj={
    [name]:'张三',
    age:18
}
console.log(obj) //{Symbol(name): '张三', age: 18}
//想要读取到name属性,需要使用obj[name]
console.log(obj[name],obj["age"]) //张三

//symbol作用2
//定义私有属性,但不是真正的私有
const _name = Symbol('name')
class Person{
    constructor(name,age){
        this[_name]=name
        this.age=age
    }
    get getName(){
        return this[_name]
    }
}

const p = new Person('李四  ',18)
console.log(p) //Person { _name: '李四', age: 18 }
console.log(p[_name])//依然可以通过symbol对象访问到,不是真正的私有
console.log('==========================')
for(let key in p){
    console.log('obj的key',key) //age,普通的遍历不到symbol属性
}

console.log('Object.keys(p)',Object.keys(p)) //['age']
console.log('Object.getOwnPropertyNames(p)',Object.getOwnPropertyNames(p)) //['age']
console.log('Object.getOwnPropertySymbols(p)',Object.getOwnPropertySymbols(p)) //[Symbol(_name)]
console.log('Reflect.ownKeys(p)',Reflect.ownKeys(p)) //['age', Symbol(_name)]



//symbol不能和其他类型进行运算,如字符串拼接,数字比较等等
// console.log('1'+s1) //报错,不能与字符串进行拼接
// console.log(1>s1) //报错,不能进行数值比较
console.log(s1.toString()+'1') //可以通过toString()转换为字符串



//symbol的全局注册表
//提供了"同一个描述"返回同一个symbol对象的symbol可共享能力,这个共享能力可以跨窗口,跨模块的浏览器级别共享
//私有用 Symbol()，共享用 Symbol.for()；描述只是备注，key 才是身份证







 